package at.ac.tuwien.swa.sparrow.peer.conf

import akka.actor.{ActorRef, ActorSystem}
import at.ac.tuwien.swa.sparrow._
import at.ac.tuwien.swa.sparrow.peer.component.RequestHandler
import at.ac.tuwien.swa.sparrow.peer.{PeerInterface, PeerActorFactory}
import at.ac.tuwien.swa.sparrow.server.PeerService
import at.ac.tuwien.swa.sparrow.server.security.AuthenticatingHttpInvokerRequestExecutor
import com.typesafe.config.ConfigFactory
import javax.inject.Inject
import org.springframework.context.annotation.{FilterType, ComponentScan, Bean, Configuration}
import org.springframework.remoting.httpinvoker.{HttpInvokerProxyFactoryBean, SimpleHttpInvokerServiceExporter}
import org.springframework.remoting.support.SimpleHttpServerFactoryBean
import scala.collection.JavaConverters._

@Configuration
@ComponentScan(value = Array("at.ac.tuwien.swa"),
	excludeFilters = Array(new ComponentScan.Filter(`type` = FilterType.ANNOTATION, value = Array(classOf[Configuration]))))
class SpringConfig {

	val system = ActorSystem("AkkaScalaSpring")
	@Inject var peerActorFactory: PeerActorFactory = _

	@Bean def actorSystem = system

	@Bean def firstPeer: ActorRef = {
		peerActorFactory.config = config
		peerActorFactory.createInstance
	}

	@Bean def config = ConfigFactory parseFile CONFIG_FILE_PEER withFallback ConfigFactory.parseResources("app.conf") getConfig "swazam"

	@Bean def peerService = {
		val factoryBean = new HttpInvokerProxyFactoryBean
		factoryBean.setServiceUrl(config getString "peerService")
		factoryBean.setServiceInterface(classOf[PeerService])
		factoryBean.setHttpInvokerRequestExecutor(AuthenticatingHttpInvokerRequestExecutor)
		factoryBean.afterPropertiesSet()
		factoryBean.getObject.asInstanceOf[PeerService]
	}

	@Bean def httpExporter(requestHandler: RequestHandler): com.sun.net.httpserver.HttpHandler = {
		val exporter = new SimpleHttpInvokerServiceExporter()
		exporter.setService(requestHandler)
		exporter.setServiceInterface(classOf[PeerInterface])
		exporter
	}

	@Bean def httpServer(requestHandler: RequestHandler) = {
		val factoryBean = new SimpleHttpServerFactoryBean()
		factoryBean.setPort(config.getInt("port"))
		factoryBean.setContexts(Map("/remoting/PeerInterface" -> httpExporter(requestHandler)).asJava)
		factoryBean
	}
}
